﻿namespace 依赖注入
{

    /// <summary>
    /// 根据特性的方式，实现自动依赖注入
    /// </summary>
    public static class RegisterServicesByAttribute
    {
        public static IServiceCollection RegisterServicesByAttributes(this IServiceCollection services) 
        {
            var allAssemblies= AppDomain.CurrentDomain.GetAssemblies();
            foreach (var item in allAssemblies)
            {
                //IsDefined方法用于确定指定类型或其派生类型的自定义属性是否应用在参数上, 布尔值，表示是否在继承链中搜索属性。
                var scopeTypes = item.GetTypes().Where(t => t.IsDefined(typeof(DiScopedAttribute), true));
                foreach (var scope in scopeTypes)
                {
                    services.AddScoped(scope.GetInterfaces().FirstOrDefault() ?? scope, scope);
                }
                var singleTypes= item.GetTypes().Where(t => t.IsDefined(typeof(DiSingletonAttribute), true));
                foreach (var single in singleTypes)
                {
                    services.AddSingleton(single.GetInterfaces().FirstOrDefault() ?? single, single);
                }
                
                var transientTypes = item.GetTypes().Where(t => t.IsDefined(typeof(DiTransientAttribute), true));
                foreach (var transient in transientTypes)
                {
                    services.AddTransient(transient.GetInterfaces().FirstOrDefault() ?? transient, transient);
                }
            }
            return services;
        }

        //在Program.cs 中使用 builder.Services.RegisterServicesByAttributes();
    }


    /// <summary>
    /// 作用域
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    public class DiScopedAttribute : Attribute { }

    /// <summary>
    /// 单列
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    public class DiSingletonAttribute : Attribute { }

    /// <summary>
    /// 瞬时
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    public class DiTransientAttribute : Attribute { }
}
